/**
 * 
 */
package com.cmcc.awareness;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.pcap4j.packet.Packet;

import com.cmcc.awareness.util.CommonUtils;

/**
 * @author Amish
 * @date 2018年12月7日 下午7:12:31
 * 
 * 字节操作符表达式：b
 * 
 * eg:
 * {b|0|0xaa}
   {b|-1|0xaa}
   {b|0|0xbb}{b|-1|0xbb}
 */
public class ProtoDatProtocolFeatureCodeElement_b implements ProtoDatProtocolFeatureCodeElement {
	private static Logger logger = LogManager.getLogger(ProtoDatProtocolFeatureCodeElement_b.class);
	
	String initialStr;

	String offset;
	String hexValue;//无0x
	
	public String appName;
	public String protocolType;
	public ProtoDatProtocolFeatureCodeElement_b(String appName,String protocolType){
		this.appName = appName;
		this.protocolType = protocolType;
	}
	
	@Override
	public String getType() {
		return "b";
	}


	@Override
	public boolean distinguish(String protocolType,jpcap.packet.Packet packet) {
		
		try{
			byte[] data = packet.data;
			
			int offsetInt = Integer.valueOf(offset);
			if(data ==null || data.length == 0)
				return false;
			
			if(offsetInt>=0 && data.length < offsetInt + 1 )
				return false;
						
		    if(offsetInt < 0 && data.length < Math.abs(offsetInt))
		    	return false;
			
			String dataHexValue;
			if(offsetInt < 0){//偏移量为负数时，表示从尾部数，第|offset|个字节
				dataHexValue = CommonUtils.byteToHexString(data[offsetInt + data.length]);
				if(dataHexValue.equalsIgnoreCase(this.hexValue)){
					//System.out.println(initialStr);
					return true;
				}
			}else{
				dataHexValue = CommonUtils.byteToHexString(data[offsetInt]);
				if(dataHexValue.equalsIgnoreCase(this.hexValue)){
					//System.out.println(initialStr);
					return true;
				}
			}
					
			return false;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Distinguish Exception -- <"+this.appName+">"+"<"+this.protocolType+"> : "+this.toString());
			return false;
		}
	}


	@Override
	public void parseSelf(String element) {		
		try{			
			this.initialStr = element;
			String[] str = element.split("\\|");
			this.offset = str[1];
			this.hexValue = str[2].substring(2);//去掉0x

		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public String toString(){
		return "{"+initialStr+"}";
	}

	@Override
	public boolean distinguish(String protocolType, Packet packet) {
		try{
			byte[] data = packet.getRawData();
			
			int offsetInt = Integer.valueOf(offset);
			if(data ==null || data.length == 0)
				return false;
			
			if(offsetInt>=0 && data.length < offsetInt + 1 )
				return false;
						
		    if(offsetInt < 0 && data.length < Math.abs(offsetInt))
		    	return false;
			
			String dataHexValue;
			if(offsetInt < 0){//偏移量为负数时，表示从尾部数，第|offset|个字节
				dataHexValue = CommonUtils.byteToHexString(data[offsetInt + data.length]);
				if(dataHexValue.equalsIgnoreCase(this.hexValue)){
					//System.out.println(initialStr);
					return true;
				}
			}else{
				dataHexValue = CommonUtils.byteToHexString(data[offsetInt]);
				if(dataHexValue.equalsIgnoreCase(this.hexValue)){
					//System.out.println(initialStr);
					return true;
				}
			}
					
			return false;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Distinguish Exception -- <"+this.appName+">"+"<"+this.protocolType+"> : "+this.toString());
			return false;
		}
	}

}
